package com.noble.meether.chat.ui.agora.act.video;

import android.graphics.Rect;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.faceunity.MRender;
import com.noble.glamour.bean.center.user.detail.UserDetail;
import com.noble.glamour.bean.my.GiftsList;
import com.noble.glamour.module.logic.application.ModuleMgr;
import com.noble.glamour.module.logic.baseui.LoadingDialog;
import com.noble.glamour.module.logic.baseui.custom.CountDownTextView;
import com.noble.glamour.module.logic.config.UrlParam;
import com.noble.glamour.module.logic.request.HttpResponse;
import com.noble.glamour.module.logic.request.RequestComplete;
import com.noble.glamour.module.util.TimerUtil;
import com.noble.library.image.ImageLoader;
import com.noble.library.log.PToast;
import com.noble.library.observe.MsgMgr;
import com.noble.library.observe.MsgType;
import com.noble.library.observe.PObserver;
import com.noble.library.utils.NoDoubleClickListener;
import com.noble.library.view.custom.state.CustomFrameLayout;
import com.noble.library.view.live.gift.GiftControl;
import com.noble.library.view.live.gift.widget.GiftModel;
import com.noble.meether.R;
import com.noble.meether.chat.ui.agora.act.base.RtcBaseActivity;
import com.noble.meether.chat.ui.agora.act.mail.RtcMsgAdapter;
import com.noble.meether.chat.ui.agora.beauty.ViewFaceBeautify;
import com.noble.meether.chat.ui.agora.dialog.listener.GiftSendListener;
import com.noble.meether.chat.ui.agora.model.AgoraConstant;
import com.noble.meether.chat.ui.agora.util.RtcJointChannel;
import com.noble.meether.chat.ui.agora.util.RtcSubUtil;
import com.noble.meether.chat.ui.agora.util.RtcTimerUtil;
import com.noble.meether.chat.ui.agora.util.RtcUtil;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import io.agora.rtc.video.VideoCanvas;

/**
 * 视频通话
 * <p>
 * Created by Su on 2017/3/17.
 */
public class RtcVideoActivity extends RtcBaseActivity implements PObserver, RequestComplete, GiftSendListener {
    private RelativeLayout rootView;
    private int lastHeight = 0;
    private LinearLayout msgTipsLayout;      // 钻石不足提示消息
    private CountDownTextView tipsCountDown; // 钻石不足提示倒计时

    private FrameLayout remoteContainer;    // 远端容器
    private FrameLayout localContainer;     // 本地容器
    private SurfaceView remoteSurfaceV;     // 远端展示控件
    private SurfaceView localSurfaceV;      // 本地展示控件
    private CustomFrameLayout videoFrame;   // 本地视频开关状态
    private ImageView btnClose;             // 关闭本地视频
    private TextView connTips;              // 女性接通提示

    private ImageView iv_head;              // 对方头像

    private UserDetail userDetail;          // 自己资料
    private UserDetail otherInfo;          // 他人资料
    private LinearLayout chatLayout;
    private RtcVideoHeadPanel headPanel;
    private ChatFootPanel footerPanel;

    private RecyclerView recyclerView;      // 消息列表展示
    private RtcMsgAdapter msgAdapter;
    private List<String> msgList;

    private GiftControl giftControl;        // 礼物特效
    private GiftModel giftModel;

    private ViewFaceBeautify faceBeautify;  // 美颜View

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (synthHandle()) {
            rootView = (RelativeLayout) getLayoutInflater().inflate(R.layout.p1_chat_video, null);
            setContentView(rootView);
            initUIandEvent();
            addGlobalListener();
            RtcJointChannel.getInstance().reqUserInfo(this);
        }
    }

    // ===================================== 初始化 ===================================================
    private void addGlobalListener() {
        rootView.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
            if (isFinishing()) return;
            Rect r = new Rect();
            getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
            int screenHeight = getWindow().getDecorView().getRootView().getHeight();
            int heightDifference = screenHeight - r.bottom;

            //键盘收起,弹出
            if (heightDifference == 0 && lastHeight > 0) {
                footerPanel.moveInputPanel(0);
            } else if (heightDifference > 0) {
                footerPanel.moveInputPanel(-heightDifference);
            }
            lastHeight = heightDifference;
        });
    }

    protected void initUIandEvent() {
        userDetail = ModuleMgr.getCenterMgr().getMyInfo();

        // 远端视频容器
        remoteContainer = findViewById(R.id.video_remote);
        remoteSurfaceV = RtcJointChannel.getInstance().getRemoteSurfaceV();
        remoteContainer.setOnClickListener(listener);

        // 本地视频容器
        connTips = findViewById(R.id.connect_tips);
        localContainer = findViewById(R.id.video_local);
        localContainer.setOnClickListener(listener);
        localSurfaceV = RtcJointChannel.getInstance().getLocalSurfaceV();
        RtcJointChannel.getInstance().setVideoContainer(remoteContainer, localContainer);

        // 美颜弹框
        faceBeautify = findViewById(R.id.chat_face_beauty);
        ModuleMgr.getRtcEnginMgr().setFaceUListener(faceBeautify);

        // 女性用户：对方镜头开关提示
        if (!userDetail.isMan()) {
            ImageView videoImg = findViewById(R.id.video_img);
            TextView videoTips = findViewById(R.id.video_tips);
            videoImg.setVisibility(View.GONE);
            videoTips.setText(getString(R.string.chat_video_open_female));
        }

        // 本地视频功能按钮
        videoFrame = findViewById(R.id.custom_video_local);
        btnClose = findViewById(R.id.btn_close_local);
        iv_head = findViewById(R.id.iv_head);
        if (userDetail.isMan()) {
            btnClose.setVisibility(View.VISIBLE);
            btnClose.setOnClickListener(listener);
            findViewById(R.id.btn_open_video).setOnClickListener(listener);
            initCountDownTimer();// 倒计时控件
        }

        // 头部布局
        LinearLayout headLayout = findViewById(R.id.chat_head_panel);
        headPanel = new RtcVideoHeadPanel(this, isOpenCamera());
        headLayout.addView(headPanel.getContentView());
        headPanel.setPanelListener(v -> {
            if (checkOverLaysPermission())
                ModuleMgr.getRtcEnginMgr().startRtcFloatService();
        });

        // 底部功能按钮
        chatLayout = findViewById(R.id.chat_faction_panel);
        footerPanel = new ChatFootPanel(this);
        chatLayout.addView(footerPanel.getContentView());

        initGiftView();
        initMsgList();
        initVideoContainer();

        ModuleMgr.getRtcEnginMgr().joinChannel(this);
    }

    /**
     * 音视频双方同步操作
     */
    private boolean synthHandle() {
        // 已经收到对方挂断消息
        if (RtcUtil.getInstance().isReceiveReject()) {
            RtcUtil.getInstance().resetReceiveReject();
            finish();
            return false;
        }

        // 等待界面已经点挂断，但是还收到接收消息
        if (RtcUtil.getInstance().isHandleUp()) {
            RtcUtil.getInstance().resetHandleUp();
            finish();
            return false;
        }
        MsgMgr.getInstance().attach(this);
        return true;
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (RtcUtil.getInstance().isHangUp()) {  // 对方用户快速挂断
            finish();
        }
    }

    // 礼物动画容器
    private void initGiftView() {
        LinearLayout giftParent = findViewById(R.id.ll_gift_parent);
        giftModel = new GiftModel();
        giftControl = new GiftControl(this);
        giftControl.setGiftLayout(giftParent, 3)
                .setDisplayMode(GiftControl.FROM_BOTTOM_TO_TOP);

        // 设置礼物消息接收监听
        if (!userDetail.isMan()) {
            RtcUtil.getInstance().setGiftSendListener(this);
        }
    }

    /**
     * 消息列表展示
     */
    private void initMsgList() {
        recyclerView = findViewById(R.id.list_msg);
        LinearLayoutManager manager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
        recyclerView.setLayoutManager(manager);
        msgAdapter = new RtcMsgAdapter();
        msgList = Collections.synchronizedList(new ArrayList<String>());
        recyclerView.setAdapter(msgAdapter);
        msgAdapter.setList(msgList);
    }

    private NoDoubleClickListener listener = new NoDoubleClickListener() {
        @Override
        public void onNoDoubleClick(View v) {
            switch (v.getId()) {
                case R.id.video_local:
                    if (userDetail.isMan())
                        btnClose.setVisibility(RtcJointChannel.getInstance().getSwitchVideo() ?
                                View.VISIBLE : View.GONE);
                    RtcJointChannel.getInstance().switchVideo();
                    break;

                case R.id.video_remote:
                    if (footerPanel == null) return;
                    footerPanel.refreshLayout();
                    break;

                case R.id.btn_open_video:   // 开启本地视频
                    openLocalVideo();
                    break;

                case R.id.btn_close_local:  // 关闭本地视频
                    closeLocalVideo();
                    break;
            }
        }
    };

    /**
     * 通话状态消息
     */
    @Override
    public void onMessage(String key, Object value) {
        try {
            switch (key) {
                case MsgType.MT_Rtc_Chat_Status:
                    Map<String, Object> data = (Map<String, Object>) value;
                    switch ((int) data.get("type")) {
                        case AgoraConstant.RTC_MSG_REJECT:     // 拒絕加入
                        case AgoraConstant.RTC_MSG_HANGON:     // 挂断
                            PToast.showShort(getString(R.string.chat_tips_user_hangup));
                            finish();
                            break;
                    }
                    break;
                case MsgType.MT_Rtc_Chat_Close_Msg:
                    finish();
                    break;
                case MsgType.MT_Rtc_Chat_Connect_Suc:
                    LoadingDialog.closeLoadingDialog();
                    runOnUiThread(() -> connTips.setVisibility(View.VISIBLE));
                    break;

                case MsgType.MT_Rtc_Chat_Video_Remote:
                    doRenderRemoteUi();
                    break;

                case MsgType.MT_Rtc_Chat_Remote_Status:
                    if ((boolean) value) {
                        onRemoteCloseVideo();
                        return;
                    }
                    onRemoteOpenVideo();
                    break;

                case MsgType.MT_Rtc_Chat_Timer_Msg:
                    if (!userDetail.isMan()) return;
                    if ((int) value == AgoraConstant.TIMER_LAST_TIPS) {
                        msgTipsLayout.setVisibility(View.VISIBLE);
                        tipsCountDown.setCountDownTimes(config().millisLeft * 1000);
                        tipsCountDown.start();
                    }
                    break;

                case MsgType.MT_MyInfo_Change:          // 个人资料变化，目前只有充值成功后接收此消息，取消余额倒计时
                    if (!userDetail.isMan()) return;
                    userDetail = ModuleMgr.getCenterMgr().getMyInfo();
                    RtcTimerUtil.getInstance().stopStatisTipsTime(); // 停止余额倒计时
                    msgTipsLayout.setVisibility(View.GONE);
                    tipsCountDown.cancel();
                    RtcSubUtil.getInstance().startVideoChatTime();  // 接通后开启轮询付费信息
                    break;

                case MsgType.MT_Msg_AvChat_MY:  // 接收消息
                    refreshMsgList(userDetail.getNickname(), value);
                    break;

                case MsgType.MT_Msg_AvChat_Other:
                    if (otherInfo == null) otherInfo = new UserDetail();
                    refreshMsgList(otherInfo.getNickname(), value);
                    break;
            }
        } catch (Exception e) {
        }
    }

    // ------------------------------ 礼物收发 ------------------------------------
    @Override
    public void sendGiftSuccess(GiftsList.GiftInfo info) {
        giftSend(info);
    }

    private void giftSend(GiftsList.GiftInfo info) {
        if (info == null) return;
        giftModel.setGiftId(String.valueOf(info.getId())).setGiftName(info.getName()).setGiftCount(info.getNum()).setGiftPic(info.getPic())
                .setSendUserName(otherInfo.getNickname()).setSendUserPic(otherInfo.getAvatar())
                .setJumpCombo(info.getNum())
                .setSendGiftTime(System.currentTimeMillis())
                .setCurrentStart(true);
        giftControl.loadGift(giftModel);
    }

    // ------------------------------ 视频相关 ------------------------------------

    private void initVideoContainer() {
        // 首次通信绑定己方视频容器
        if (RtcJointChannel.getInstance().getFirstVideo()) {
            setupLocalVideo();
            RtcJointChannel.getInstance().setFirstVideo(false);
            return;
        }

        // 男性用户
        if (userDetail.isMan()) {
            // 开启摄像头
            if (isOpenCamera()) {
                RtcJointChannel.getInstance().setSwitchVideo(true);
                videoFrame.show(R.id.rl_video_local_open);
                RtcJointChannel.getInstance().initSurfaceV();
                return;
            }

            // 关闭摄像头
            videoFrame.show(R.id.ll_local_video_close);
            RtcJointChannel.getInstance().setRemoteToRemote();
            return;
        }

        // 女性用户且对方开启了摄像头
        if (ModuleMgr.getRtcEnginMgr().getEngineConfig().mOpenCamera) {
            RtcJointChannel.getInstance().setSwitchVideo(true);
            onRemoteOpenVideo();
            return;
        }

        // 对方未开启
        videoFrame.show(R.id.ll_local_video_close);
        RtcJointChannel.getInstance().setLocalToRemote();
    }

    /**
     * 是否开启本地摄像头(男性用户)
     */
    private boolean isOpenCamera() {
        return config().mCamera == 1;
    }

    /**
     * 绑定远端视频容器
     */
    private void doRenderRemoteUi() {
        runOnUiThread(() -> {
            //RtcSubUtil.getInstance().startPicTime();   // 开启鉴黄图片上传轮询

            if (userDetail.isMan()) {  // 男性用户, 直接绑定远端视频
                RtcJointChannel.getInstance().setRemoteToRemote();
                return;
            }
            setRemoteView();   // 女性用户
        });
    }

    private void setRemoteView() {
        videoFrame.show(R.id.rl_video_local_open);
        if (!RtcJointChannel.getInstance().getSwitchVideo()) {
            RtcJointChannel.getInstance().removeRemoteView();
            remoteContainer.removeAllViews();
            remoteContainer.addView(remoteSurfaceV);
        } else {
            RtcJointChannel.getInstance().removeRemoteView();
            localContainer.removeAllViews();
            localContainer.addView(remoteSurfaceV);
        }
        RtcJointChannel.getInstance().switchVideo();
    }

    /**
     * 绑定已方视频容器
     */
    private void setupLocalVideo() {
        ModuleMgr.getRtcEnginMgr().getRtcEngine().setupLocalVideo(new VideoCanvas(localSurfaceV, VideoCanvas.RENDER_MODE_HIDDEN, 0));

        // 女性用户首次大视频展示
        if (!userDetail.isMan()) {
            RtcJointChannel.getInstance().setSwitchVideo(true);
            remoteContainer.removeAllViews();
            RtcJointChannel.getInstance().removeLocalView();
            remoteContainer.addView(localSurfaceV);
            ModuleMgr.getRtcEnginMgr().preview(true, localSurfaceV);
            videoFrame.show(R.id.ll_local_video_close);
        }

        // 男性用户
        else {
            if (isOpenCamera()) {  // 首次开启本地视频
                videoFrame.show(R.id.rl_video_local_open);
                localContainer.removeAllViews();
                RtcJointChannel.getInstance().removeLocalView();
                localContainer.addView(localSurfaceV);
                ModuleMgr.getRtcEnginMgr().preview(true, localSurfaceV);
            } else {
                videoFrame.show(R.id.ll_local_video_close);
                ModuleMgr.getRtcEnginMgr().getRtcEngine().muteLocalVideoStream(true);
            }
        }
        RtcSubUtil.getInstance().setIntervalConfig(config().mIntervalFirstTime, config().mIntervalTime);
    }

    /**
     * 开启本地视频发送流(男性用户)
     */
    private void openLocalVideo() {
        headPanel.refreshCamera(false);
        videoFrame.show(R.id.rl_video_local_open);
        ModuleMgr.getRtcEnginMgr().getRtcEngine().muteLocalVideoStream(false);
        ModuleMgr.getRtcEnginMgr().getEngineConfig().mCamera = 1;

        TimerUtil.beginTime(() -> {
            localContainer.removeAllViews();
            remoteContainer.removeAllViews();
            RtcJointChannel.getInstance().removeLocalView();
            RtcJointChannel.getInstance().removeRemoteView();
            localContainer.addView(localSurfaceV);
            remoteContainer.addView(remoteSurfaceV);
            ModuleMgr.getRtcEnginMgr().preview(true, localSurfaceV);   // 开启本地视频预览
        }, 200);
    }

    /**
     * 关闭本地视频发送流(男性用户)
     */
    private void closeLocalVideo() {
        runOnUiThread(() -> {
            headPanel.refreshCamera(true);
            localContainer.removeAllViews();
            ModuleMgr.getRtcEnginMgr().preview(false, null);   // 关闭本地视频预览
            ModuleMgr.getRtcEnginMgr().getRtcEngine().muteLocalVideoStream(true);
            ModuleMgr.getRtcEnginMgr().getEngineConfig().mCamera = 2;
            videoFrame.show(R.id.ll_local_video_close);
        });
    }

    /**
     * 远端关闭视频 (女性用户)
     */
    private void onRemoteCloseVideo() {
        runOnUiThread(() -> {
            //RtcSubUtil.getInstance().stopPicTime();   // 关闭鉴黄图片上传轮询
            // 此时大图展示本地，直接关闭
            if (RtcJointChannel.getInstance().getSwitchVideo()) {
                localContainer.removeAllViews();
                videoFrame.show(R.id.ll_local_video_close);
                return;
            }

            // 此时小图展示本地, 切换到大图
            RtcJointChannel.getInstance().setSwitchVideo(true);
            remoteContainer.removeAllViews();
            localContainer.removeAllViews();
            RtcJointChannel.getInstance().removeLocalView();
            remoteContainer.addView(localSurfaceV);
            videoFrame.show(R.id.ll_local_video_close);
            ModuleMgr.getRtcEnginMgr().preview(true, localSurfaceV);
        });
    }

    /**
     * 远端开启视频（女性用户）
     */
    private void onRemoteOpenVideo() {
        runOnUiThread(() -> {
            //RtcSubUtil.getInstance().startPicTime();   // 开启鉴黄图片上传轮询
            videoFrame.show(R.id.rl_video_local_open);
            // 此时小图展示本地
            if (!RtcJointChannel.getInstance().getSwitchVideo()) {
                remoteContainer.removeAllViews();
                RtcJointChannel.getInstance().removeRemoteView();
                remoteContainer.addView(remoteSurfaceV);
                return;
            }

            // 此时大图展示本地, 直接延迟切换视图
            TimerUtil.beginTime(() -> RtcJointChannel.getInstance().switchVideo(), 100);
        });
    }

    // ===================================== 本地计时统计 ===================================================

    /**
     * 余额不足提示
     */
    private void initCountDownTimer() {
        msgTipsLayout = findViewById(R.id.msg_tips);
        tipsCountDown = findViewById(R.id.tv_countDown);
        RtcTimerUtil.getInstance().addTimer(tipsCountDown);
        TextView tipsTxt = findViewById(R.id.time_left_tips);

        // 女号都是邀请流程，扣费方全部为男方扣费
        if (!ModuleMgr.getCenterMgr().getMyInfo().isMan())
            tipsTxt.setText(getString(R.string.chat_tips_other_no_diamond));

        if (config().millisLeft > 0 && config().millisLeft <= AgoraConstant.CHAT_COST_PROMPT) {
            msgTipsLayout.setVisibility(View.VISIBLE);
            tipsCountDown.setCountDownTimes(config().millisLeft * 1000);
            tipsCountDown.start();
        }
    }

    private void refreshMsgList(String name, Object value) {
        try {
            String msg = (String) value;
            if (TextUtils.isEmpty(msg)) return;
            msgList.add(name + "：" + msg);
            msgAdapter.notifyItemInserted(msgList.size() - 1);
            recyclerView.smoothScrollToPosition(msgList.size() - 1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onRequestComplete(HttpResponse response) {
        if (response.getUrlParam() == UrlParam.reqMyInfo) {
            if (!response.isOk()) return;
            otherInfo = (UserDetail) response.getBaseData();
            ImageLoader.loadCircleAvatar(this, otherInfo.getAvatar(), iv_head);
            headPanel.refreshInfo(otherInfo);
        }
    }

    @Override
    public void finish() {
        super.finish();
        LoadingDialog.closeLoadingDialog();
        MsgMgr.getInstance().detach(this);
        RtcUtil.getInstance().resetSynchStatus();   // 重置挂断状态
        if (giftControl != null) { // 礼物特效销毁动画
            giftControl.cleanAll();
        }
        RtcUtil.getInstance().setGiftSendListener(null);

        // 处于悬浮窗、跳到视频页面， 则只需释放本地Timer计时
        if (RtcJointChannel.getInstance().getFloatStatus()) {
            ModuleMgr.getRtcEnginMgr().releaseLocalTimer();
            return;
        }
        // 全部回收
        MRender.destroy();
        if (faceBeautify != null) {
            faceBeautify.setBeautifyInterface(null);
            ((ViewGroup) faceBeautify.getParent()).removeView(faceBeautify);
            faceBeautify = null;
        }
        RtcSubUtil.getInstance().release();
        RtcJointChannel.getInstance().releaseView();
        ModuleMgr.getRtcEnginMgr().releaseAll();
        MsgMgr.getInstance().sendMsg(MsgType.MT_Update_MyInfo, null);
    }
}
